/*
 * @Author: C.
 * @Date: 2025-04-15 16:26:12
 */
/**
 * 从 'spinner' 库中导入 Ora 类型，用于类型定义。
 */
import type { Ora } from 'ora';

/**
 * 导入 'ora' 库，用于创建命令行加载指示器。
 */
import ora from 'ora';

/**
 * 定义 SpinnerOptions 接口，用于配置加载指示器的提示信息和标题。
 */
interface SpinnerOptions {
  // 回调函数执行失败时显示的提示信息，可选参数
  failedText?: string;
  // 回调函数执行成功时显示的提示信息，可选参数
  successText?: string;
  // 加载指示器开始时显示的标题，必填参数
  title: string;
}

/**
 * 使用 ora 库创建一个加载指示器，在执行异步回调函数时显示加载状态。
 * 根据回调函数的执行结果，显示成功或失败的提示信息。
 *
 * @template T - 回调函数返回值的类型。
 * @param {SpinnerOptions} options - 配置选项对象。
 * @param {() => Promise<T>} callback - 要执行的异步回调函数。
 * @returns {Promise<T>} - 返回一个 Promise，该 Promise 解析为回调函数的返回值。
 * @throws {Error} - 如果回调函数执行失败，将抛出错误。
 */
export async function spinner<T>(
  // 包含加载指示器相关提示信息和标题的配置对象
  { failedText, successText, title }: SpinnerOptions,
  // 要执行的异步回调函数
  callback: () => Promise<T>,
): Promise<T> {
  // 创建一个 ora 加载指示器并启动，显示指定的标题
  const loading: Ora = ora(title).start();

  try {
    // 执行异步回调函数并等待结果
    const result = await callback();
    // 回调函数执行成功，显示成功提示信息
    loading.succeed(successText || 'Success!');
    return result;
  } catch (error) {
    // 回调函数执行失败，显示失败提示信息
    loading.fail(failedText || 'Failed!');
    throw error;
  } finally {
    // 无论回调函数执行成功还是失败，都停止加载指示器
    loading.stop();
  }
}
